package com.uniandes.edu.co.dto;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.swing.tree.DefaultTreeModel;

import com.uniandes.edu.co.anotaciones.LogT;
import com.uniandes.edu.co.anotaciones.LogsT;
import com.uniandes.edu.co.controlador.ControladorCiclo;
import com.uniandes.edu.co.controlador.ControladorDefectos;
import com.uniandes.edu.co.controlador.ControladorInterrupciones;
import com.uniandes.edu.co.controlador.ControladorPersona;
import com.uniandes.edu.co.controlador.ControladorPlanQ;
import com.uniandes.edu.co.controlador.ControladorTarea;
import com.uniandes.edu.co.excepciones.ExcepcionExiste;
import com.uniandes.edu.co.excepciones.ExcepcionParseInt;
import com.uniandes.edu.co.excepciones.ExcepcionVacio;
import com.uniandes.edu.co.procesar.defecto.ProcesarDefectos;
import com.uniandes.edu.co.procesar.interrupcion.ProcesarInterrupciones;

public class Tsp {
	
	private List <Ciclo> ciclos;
	
	private List <Persona> personas;
	
	private String archivoTsp;
	
	static private Tsp solitario = null;

    static public Tsp getSingleton() {
        if (solitario == null) {
            solitario = new Tsp("./data/tsp.dat");
        }
        return solitario;
    }
    
   public Tsp(){
	   this.personas=new LinkedList<Persona>();
		this.ciclos=new LinkedList<Ciclo>();
   }
    
	public Tsp(String archivo)
	{
		this.personas=new LinkedList<Persona>();
		this.ciclos=new LinkedList<Ciclo>();
		CargarTsp(archivo);
		
	}
    
	@SuppressWarnings("unchecked")
	public void CargarTsp(String nombreArchivoTsp) {
		archivoTsp=nombreArchivoTsp;
		File archivo=new File(archivoTsp);
		if(archivo.exists()){
			try {
				FileInputStream fis=new FileInputStream(archivo);
				ObjectInputStream ois=new ObjectInputStream(fis);
				ciclos =(LinkedList)ois.readObject();
                personas=(LinkedList)ois.readObject();
                fis.close();
                ois.close( );
			} catch (Exception e) {
				e.printStackTrace();
			}
		}else{
			ciclos=new ArrayList<Ciclo>();
			personas=new ArrayList<Persona>();
			System.out.println("personas.size() "+ personas.size());
		}
	}

	public List<Ciclo> getCiclos() {
		return ciclos;
	}

	public void setCiclos(List<Ciclo> ciclos) {
		this.ciclos = ciclos;
	}

	public List<Persona> getPersonas() {
		return personas;
	}

	public void setPersonas(List<Persona> personas) {
		this.personas = personas;
	}
	
	@LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public void agregarNuevoCiclo(String idCiclo, String estrategia, String planDeDesarrollo, 
			LinkedList<Requerimiento> listadoRequerimiento) throws ExcepcionExiste, ExcepcionVacio, ExcepcionParseInt{
    	
    	ControladorCiclo.getSingleton().agregarCiclo(idCiclo, estrategia, planDeDesarrollo, listadoRequerimiento,  this.ciclos);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public void agregarRequerimiento(String idRequerimiento, String descripcion, LinkedList<Requerimiento> listadoRequermiento) throws ExcepcionExiste, ExcepcionVacio
    {
    	ControladorCiclo.getSingleton().agregarRequerimiento(idRequerimiento, descripcion, listadoRequermiento);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public void modificarRequerimiento(String idRequerimiento, String descripcion, LinkedList<Requerimiento> listadoRequerimiento) throws ExcepcionVacio, ExcepcionExiste{
    	ControladorCiclo.getSingleton().modificarRequerimientos(idRequerimiento, descripcion, listadoRequerimiento);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public Requerimiento obtenerRequerimiento(String idRequerimiento, LinkedList<Requerimiento> listado)
    {
    	return ControladorCiclo.getSingleton().obtenerRequerimiento(idRequerimiento,listado);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public void eliminarRequerimiento(String idRequerimiento, LinkedList<Requerimiento> listado) throws ExcepcionExiste, ExcepcionVacio
    {
    	ControladorCiclo.getSingleton().eliminarRequerimientos(idRequerimiento, listado);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public void eliminarCiclo(String idCiclo) throws ExcepcionExiste, ExcepcionVacio, ExcepcionParseInt
    {
    	ControladorCiclo.getSingleton().eliminarCiclo(idCiclo, this.ciclos);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public Object[][] tablaCiclos()
    {
    	return ControladorCiclo.getSingleton().tablaCiclos(this.ciclos);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public Object[] encabezadosCiclo()
    {
    	return ControladorCiclo.getSingleton().encabezadosCiclo();
    }
   
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public Ciclo obtenerCiclo(String idCiclo) throws ExcepcionParseInt, ExcepcionVacio
    {
    	return ControladorCiclo.getSingleton().obtenerCiclo(idCiclo, this.ciclos);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public void modificarCiclo(String idCiclo, String estrategia, String planDeDesarrollo) throws ExcepcionExiste, ExcepcionVacio, ExcepcionParseInt
    {
    	
    	 ControladorCiclo.getSingleton().ModificarCiclo(idCiclo, estrategia, planDeDesarrollo, this.ciclos);
    }
    
    @LogsT({@LogT(date="21/03/2011", taskId=11, idCiclo=2, idPersona=20112, porcentajeRealValorGanado=1, min=2)})
    public DefaultTreeModel consultarTareasEnArbol()
    {
    	return ControladorCiclo.getSingleton().consultarTareasEnArbol(this.ciclos);
    }
    
    public void agregarPersona(String idPersona, String nomPersona, 
    		String rolPersona, List <Persona> lPersona)throws ExcepcionVacio,
    		ExcepcionExiste{
        ControladorPersona.getSingleton().agregarPersona(idPersona, nomPersona, rolPersona, lPersona);
    }
    
    public void modificarPersona(String idPersona, String nomPersona, 
    		String rolPersona, List <Persona> lPersona)throws ExcepcionVacio, ExcepcionExiste{
    	ControladorPersona.getSingleton().modificarPersona(idPersona, nomPersona, rolPersona, lPersona);
    }
    
    public void eliminarPersona(String idPersona, 
    		List <Persona> lPersona)throws ExcepcionVacio{
    	ControladorPersona.getSingleton().eliminarPersona(idPersona, lPersona);
    }
    
    public Persona consultarPersona(String idPersona, 
    		List <Persona> lPersona)throws ExcepcionVacio{
    	Persona persona=null;
    	persona=ControladorPersona.getSingleton().consultarPersona(idPersona, lPersona);
    	return persona;
    }
    
    public Persona consultarPersonaNombre(String nomPersona, 
    		List <Persona> lPersona)throws ExcepcionVacio{
    	Persona persona=null;
    	persona=ControladorPersona.getSingleton().consultarPersonaNombre(nomPersona, lPersona);
    	return persona;
    }
    
    public void agregarTarea(String idTarea, String descripcion,
			String tiempoEstimado, String valorGanadoEstimado, String locsEstimado,
			String idPersona, List <Tarea> lTarea)throws ExcepcionVacio,
    		ExcepcionExiste, ExcepcionParseInt{
        ControladorTarea.getSingleton().agregarTarea(idTarea, descripcion, tiempoEstimado, valorGanadoEstimado, locsEstimado, idPersona, lTarea);
    }
    
    public void modificarTarea(String idTarea, String descripcion,
			String tiempoEstimado, String valorGanadoEstimado, String locsEstimado,
			String idPersona, List <Tarea> lTarea)throws ExcepcionVacio, ExcepcionExiste, ExcepcionParseInt{
    	ControladorTarea.getSingleton().modificarTarea(idTarea, descripcion, tiempoEstimado, valorGanadoEstimado, locsEstimado, idPersona, lTarea);
    }
    
    public void eliminarTarea(String idTarea, List <Tarea> lTarea)throws ExcepcionVacio{
    	ControladorTarea.getSingleton().eliminarTarea(idTarea, lTarea);
    }
    
    public Tarea consultarTarea(String idTarea, List <Tarea> lTarea)throws ExcepcionVacio{
    	Tarea Tarea=null;
    	Tarea=ControladorTarea.getSingleton().consultarTareaId(idTarea, lTarea);
    	return Tarea;
    }
    
    public String consultarTareasCiclo(String idTarea, String idCiclo)throws ExcepcionVacio{
    	String retorno=null;
    	retorno=ControladorTarea.getSingleton().consultarTareaCiclo(idTarea, idCiclo);
    	return retorno;
    }
    
    public void agregarPlanQ(String planificacionInyectado, String disenioInyectado, 
    		String codificacionInyectado, String inspeccionInyectado, 
    		String pruebasInyectado, String postmortemInyectado,
    		String planificacionPlaneado, String disenioPlaneado, 
    		String codificacionPlaneado, String inspeccionPlaneado, 
    		String pruebasPlaneado, String postmortemPlaneado, Ciclo cic)throws ExcepcionVacio,
    		ExcepcionParseInt{
        ControladorPlanQ.getSingleton().agregarPlanQ(planificacionInyectado, disenioInyectado, 
        		codificacionInyectado, inspeccionInyectado, pruebasInyectado, postmortemInyectado, 
        		planificacionPlaneado, disenioPlaneado, codificacionPlaneado, inspeccionPlaneado, 
        		pruebasPlaneado, postmortemPlaneado, cic);
    }
    
    public void eliminarPlanQ(Ciclo cic)throws ExcepcionVacio,
    		ExcepcionParseInt{
        ControladorPlanQ.getSingleton().eliminarPlanQ(cic);
    }
	
	public void salvarTsp() throws Exception{
        try{
        	FileOutputStream fos=new FileOutputStream(archivoTsp);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            /*Ciclo c=new Ciclo(1, "1", "1", new LinkedList <Requerimiento> ());
            Ciclo c2=new Ciclo(2, "2", "2", new LinkedList <Requerimiento> ());
            Ciclo c3=new Ciclo(3, "3", "3", new LinkedList <Requerimiento> ());
            ciclos.add(c);
            ciclos.add(c2);
            ciclos.add(c3);*/
            oos.writeObject(ciclos);
            oos.writeObject(personas);
            fos.close();
            oos.close();
            /*for (Persona p:personas) {
            	System.out.println("personas.nombre: "+p.getNombre());
			}
            for (Ciclo c:ciclos) {
            	List <Tarea> lt=c.getTareas();
            	System.out.println("ciclo: "+c.getIdCiclo());
            	for (Tarea t:lt) {
            		System.out.println("tarea: "+t.getIdTarea()+" descripcion: "+t.getDescripcion()+" idp "+t.getIdPersona());
            	}
            	List <Defecto> ld=c.getDefectos();
            	for (Defecto d:ld) {
            		System.out.println("defecto: "+d.getIdDefecto()+" descripcion: "+d.getDescripcion());
            	}
			}*/
        }
        catch( IOException e ){
            e.printStackTrace();
        }
    }
	
	public boolean agregarDefecto(String idDefecto,String descripcion,String idCiclo)
	{
		try
		{
			Ciclo ciclo = this.obtenerCiclo(idCiclo);
			return ControladorDefectos.getSingleton().agregarDefecto(idDefecto, descripcion,ciclo.getDefectos());
		}
		catch(Exception ex )
		{
			ex.printStackTrace();
			return false;
		}
	}
	
	public Defecto buscarDefecto(String idDefecto,String idCiclo)
	{
		try
		{
			Ciclo ciclo = this.obtenerCiclo(idCiclo);
			return ProcesarDefectos.getSingleton().buscarDefecto(idDefecto, ciclo.getDefectos());
		}
		catch(Exception ex )
		{
			ex.printStackTrace();
			return null;
		}
	}
	
	public boolean modificarDefecto(String idDefecto,String descripcion,String idCiclo)
	{
		try
		{
			Ciclo ciclo = this.obtenerCiclo(idCiclo);
			return ControladorDefectos.getSingleton().modificarDefecto(idDefecto, descripcion, ciclo.getDefectos());
		}
		catch(Exception ex )
		{
			ex.printStackTrace();
			return false;
		}
	}
	
	public boolean eliminarDefecto(String idDefecto,String idCiclo)
	{
		try
		{
			Ciclo ciclo = this.obtenerCiclo(idCiclo);
			return ControladorDefectos.getSingleton().eliminarDefecto(idDefecto,ciclo.getDefectos());
		}
		catch(Exception ex )
		{
			ex.printStackTrace();
			return false;
		}
		
	}
	
	public boolean agregarInterrrupcion(String idInterrupcion,String descripcion,String idCiclo)
	{
		try
		{
			Ciclo ciclo = this.obtenerCiclo(idCiclo);
			return ControladorInterrupciones.getSingleton().agregarInterrupcion(idInterrupcion, descripcion,ciclo.getInterrupciones());
		}
		catch(Exception ex )
		{
			ex.printStackTrace();
			return false;
		}
	}
	
	public Interrupcion buscarInterrupcion(String idInterrupcion, String idCiclo)
	{
		try
		{
			Ciclo ciclo = this.obtenerCiclo(idCiclo);
			return ProcesarInterrupciones.getSingleton().buscarInterrupcion(idInterrupcion,ciclo.getInterrupciones());
		}
		catch(Exception ex )
		{
			ex.printStackTrace();
			return null;
		}
	}
	
	public boolean modificarInterrupcion(String idInterrupcion,String descripcion,String idCiclo)
	{
		try
		{
			Ciclo ciclo = this.obtenerCiclo(idCiclo);
			return ControladorInterrupciones.getSingleton().modificarInterrupcion(idInterrupcion, descripcion, ciclo.getInterrupciones());
		}
		catch(Exception ex )
		{
			ex.printStackTrace();
			return false;
		}
	}
	
	public boolean eliminarInterrupcion(String idInterrupcion, String idCiclo)
	{
		try
		{
			Ciclo ciclo = this.obtenerCiclo(idCiclo);
			return ControladorInterrupciones.getSingleton().eliminarInterrupcion(idInterrupcion, ciclo.getInterrupciones());
		}
		catch(Exception ex )
		{
			ex.printStackTrace();
			return false;
		}
	}

}
